# coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
import os
import time
import zipfile
from datetime import datetime

from flask import render_template, url_for, redirect, flash, current_app, request, send_from_directory
from flask_login import login_required, login_user, logout_user, current_user
from werkzeug.security import generate_password_hash

from .. import files, db
from . import main
from .forms import LoginForm, FileForm, TaskForm, PasswordForm
from ..decorators import admin_required
from ..models import User, Task


@main.route('/')
@login_required     # 要放在路由的下面，否则无效
def taskList():
    # 按时间逆序，时间相同时比较id，id大靠前
    tasks = Task.query.order_by(Task.task_deadline.desc(), Task.id.desc())
    return render_template('main/taskList.html', tasks=tasks)


@main.route('/addTask', methods=['GET', 'POST'])
@login_required
@admin_required
def addTask():
    form = TaskForm()
    if form.validate_on_submit():
        task_name = form.taskName.data
        task_description = form.taskDescription.data
        task_deadline = form.taskDeadLine.data
        task = Task(task_name, task_description, task_deadline)
        try:
            os.makedirs(
                current_app.config['UPLOADED_FILES_DEST'] + '/' + task_name)
            flash(u"创建任务文件夹成功", 'success')
        except Exception as e:
            raise e
            flash(u"创建任务文件夹失败", 'warning')
        db.session.add(task)
        db.session.commit()
        return redirect(url_for('main.taskList'))
    return render_template('main/addTask.html', form=form)


@main.route('/deleteTask/<int:id>')
@login_required
@admin_required
def deleteTask(id):
    task = Task.query.get(id)
    if task is not None:
        try:
            deleteTaskFolder(
                current_app.config['UPLOADED_FILES_DEST'] + '/' + task.task_name)
            db.session.delete(task)
            db.session.commit()
            flash(u'任务成功删除！', 'success')
        except Exception as e:
            flash(u'任务删除失败', 'warning')
    else:
        flash(u'未找到该任务', 'info')
    return redirect(url_for('main.taskList'))


@main.route('/taskDetail/<int:id>')
@login_required
def taskDetail(id):
    task = Task.query.filter_by(id=id).first_or_404()
    try:
        taskList = os.listdir(
            current_app.config['UPLOADED_FILES_DEST'] + '/' + task.task_name)
        taskList.sort()
    except Exception as e:
        taskList = []

    taskDeadLineStr = datetime.strftime(
        task.task_deadline, "%Y-%m-%d %H:%M:%S")    # 将datetime格式时间转换为字符串格式
    # 将字符串格式转换成struct_time格式
    taskDeadLineTime = time.strptime(taskDeadLineStr, "%Y-%m-%d %H:%M:%S")
    # 将struct_time格式时间转换成时间戳
    if (time.mktime(taskDeadLineTime) - time.time()) > 0:
        form = FileForm()
    else:
        form = None

    return render_template('main/taskDetail.html', task=task, taskList=taskList, form=form)


@main.route('/deleteFile/<int:id>/<filePath>')
@login_required
def deleteFile(id, filePath):
    if current_user.username not in filePath:
        flash(u'要删除的文件不属于您,删除失败', 'danger')
        return redirect(url_for('main.taskDetail', id=id))

    task = Task.query.get(id)
    file_path = current_app.config[
        'UPLOADED_FILES_DEST'] + '/' + task.task_name + '/' + filePath
    if os.path.exists(file_path):
        try:
            os.remove(file_path)
            flash(u'文件删除成功', 'success')
        except Exception as e:
            # raise e
            pass
    else:
        flash(u'文件删除失败', 'warning')
    return redirect(url_for('main.taskDetail', id=id))


@main.route('/upload', methods=['POST'])
@login_required
def doUpload():
    form = FileForm()
    if form.validate_on_submit():
        task = Task.query.filter_by(
            id=request.form.get('taskId')).first_or_404()

        taskDeadLineStr = datetime.strftime(
            task.task_deadline, "%Y-%m-%d %H:%M:%S")    # 将datetime格式时间转换为字符串格式
        # 将字符串格式转换成struct_time格式
        taskDeadLineTime = time.strptime(taskDeadLineStr, "%Y-%m-%d %H:%M:%S")
        # 将struct_time格式时间转换成时间戳
        if (time.mktime(taskDeadLineTime) - time.time()) < 0:
            flash(u'超过任务截止日期，禁止提交', 'danger')
        else:
            filename = str(current_user.xh) + '-' + current_user.username + \
                '.' + form.file.data.filename.rsplit('.', 1)[1]
            folder = task.task_name

            if not os.path.exists(current_app.config['UPLOADED_FILES_DEST'] + '/' + task.task_name + '/' + filename):
                filename = files.save(
                    storage=form.file.data, folder=folder, name=filename)
                # file_url = files.url(filename)
                flash(u'任务提交成功', 'success')  # u'任务提交成功'
            else:
                flash(u'任务文件已存在,请删除后在提交', 'warning')
    else:
        flash(u'任务提交失败,仅允许上传 jpg png rar zip 格式', 'warning')
    return redirect(url_for('main.taskDetail', id=request.form.get('taskId')))


@main.route('/downloadTask/<int:id>')
@login_required
@admin_required
def downloadTask(id):
    task = Task.query.get_or_404(id)
    taskZipPath =  current_app.config[
        'UPLOADED_FILES_DEST'] + '/' + task.task_name
    taskZipFile = taskZipPath + '/' + task.task_name + '.zip'
    if os.path.exists(taskZipFile): # 删除已存在的压缩文件
        os.remove(taskZipFile)

    # 尝试生成压缩文件
    try:
        fileList = os.listdir(taskZipPath)
        with zipfile.ZipFile(taskZipPath+'/' + task.task_name + '.zip', 'w') as zf:
            for f in fileList:
                zf.write(taskZipPath+'/'+f, f, zipfile.ZIP_DEFLATED)
    except Exception as e:
        raise e
    

    return send_from_directory(taskZipPath,task.task_name+'.zip',as_attachment=True)



#def downloadTask(id):
#    task = Task.query.get_or_404(id)
#    taskZipPath = current_app.config[
#        'UPLOADED_FILES_DEST'] + '/' + task.task_name
#    if not os.path.exists(taskZipPath+'/'+task.task_name + '.zip'):
#        try:
#            fileList = os.listdir(taskZipPath)
#            with zipfile.ZipFile(taskZipPath+'/' + task.task_name + '.zip', 'w') as zf:
#                for f in fileList:
#                    zf.write(taskZipPath+'/'+f, f, zipfile.ZIP_DEFLATED)
#        except Exception as e:
#            raise e
#    tar_url = files.url(task.task_name+'/'+task.task_name+'.zip')
#    return redirect(tar_url)


@main.route('/documents')
@login_required
def documents():
    try:
        docList = os.listdir(
            current_app.config['UPLOADED_FILES_DEST'] + '/' + current_app.config['DOCUMENT_FILES_DEST'])
    except Exception as e:
        docList = []
    if current_user.isAdmin():
        form = FileForm()
    else:
        form = None
    return render_template('main/documents.html', docList=docList, form=form)


@main.route('/uploadDoc', methods=['POST'])
@login_required
@admin_required
def uploadDoc():
    form = FileForm()
    if form.validate_on_submit():
        filename = form.file.data.filename
        folder = current_app.config['DOCUMENT_FILES_DEST']
        if not os.path.exists(current_app.config['UPLOADED_FILES_DEST'] + '/' + folder):
            os.makedirs(
                current_app.config['UPLOADED_FILES_DEST'] + '/' + folder)
        if not os.path.exists(current_app.config['UPLOADED_FILES_DEST'] + '/' + folder + '/' + filename):
            filename = files.save(
                storage=form.file.data, folder=folder, name=filename)
            flash(u'文档上传成功', 'success')
            return redirect(url_for('main.documents'))
        else:
            flash(u'该文档已存在','warning')
            return redirect(url_for('main.documents'))
    flash(u'文档上传失败，仅允许上传 jpg png rar zip 格式', 'info')
    return redirect(url_for('main.documents'))


@main.route('/deleteDoc/<filename>')
@login_required
@admin_required
def deleteDoc(filename):
    file_path = current_app.config[
        'UPLOADED_FILES_DEST'] + '/' + current_app.config['DOCUMENT_FILES_DEST'] + '/' + filename
    if os.path.exists(file_path):
        try:
            os.remove(file_path)
            flash(u'文件删除成功', 'success')
        except Exception as e:
            # raise e
            pass
    else:
        flash(u'文件不存在，删除失败', 'info')
    return redirect(url_for('main.documents'))


@main.route('/downloadDoc/<fileName>')
@login_required
def downloadDoc(fileName):
    if fileName:
        doc_url = files.url(
            current_app.config['DOCUMENT_FILES_DEST'] + '/' + fileName)
        return redirect(doc_url)
    return redirect(url_for('main.documents'))


@main.route('/changePassword', methods=['GET', 'POST'])
@login_required
def changePassword():
    form = PasswordForm()
    if form.validate_on_submit():
        if form.new.data != form.confirm.data:
            flash(u'两次新密码不一致，请重新输入','warning')
        elif not current_user.verify_password(form.current.data):
            flash(u'当前密码错误', 'danger')
        else:
            current_user.password = generate_password_hash(form.new.data)
            db.session.add(current_user)
            db.session.commit()
            flash(u'修改密码成功', 'success')
            return redirect(url_for('main.taskList'))
    return render_template('main/changePassword.html', form=form)


@main.route('/login', methods=['GET', 'POST'])
def login():
    loginForm = LoginForm()
    if loginForm.validate_on_submit():
        user = User.query.filter_by(xh=loginForm.xh.data).first()
        if user and user.verify_password(loginForm.password.data):
            login_user(user, False)
            flash(u'欢迎回来，%s ' % user.username, 'success')
            return redirect(url_for('main.taskList'))
        else:
            flash(u'学号或密码错误', 'warning')
            return redirect(url_for('main.login'))

    return render_template('main/login.html', form=loginForm)


@main.route('/logout', methods=['GET'])
@login_required
def logout():
    logout_user()
    return redirect(url_for('main.taskList'))


def deleteTaskFolder(path):
    for file in os.listdir(path):
        file_path = os.path.join(path, file)
        if os.path.isfile(file_path):
            os.remove(file_path)
    os.rmdir(path)
